#include "zbnnmw.h"
#include<QString>
#include<QSettings>
#include<QSize>
#include<QDockWidget>
#include<stdlib.h>
#include<QDebug>
#include<QTime>


const int OffsetIncrement=5;
const QString ShowGrid("ShoeGrid");
ZBNNMW::ZBNNMW(QWidget *parent) :
    QWidget(parent),backgroundGrid(0),addOffset(OffsetIncrement),
    pasteOffset(OffsetIncrement)

{
    createSceneAndView();
    viewShowGrid();
    timer=new QTimer(this);
    timer->setInterval(10000);
    timer->start();
    connect(timer,SIGNAL(timeout()),this,SLOT(UpdateMap()));
    connect(scene,SIGNAL(selectionChanged()),this,SLOT(Domessage()));
    connect(this,SIGNAL(senMessage(ZigBeeNode*)),this,SLOT(recveMessage(ZigBeeNode*)));
}
void ZBNNMW::Domessage(){

    QList<QGraphicsItem*>items=scene->selectedItems();
    if (items.isEmpty()) return;
    Nodeitem=static_cast<ZigBeeNode*>(items.at(0));
    if(Nodeitem!=NULL)
        emit senMessage(Nodeitem);
}
void ZBNNMW::recveMessage(ZigBeeNode *Nodeitem){
    showInfoItem->setHtml("<b><font color=red>" + trUtf8("<li>设备名:%1</li><li>描述:%2</li><li>值:%3</li><li>时间:%4</li>")
                          .arg(Nodeitem->ge_NodeData()->getName())
                          .arg(Nodeitem->ge_NodeData()->getDevDescription())
                          .arg(Nodeitem->getNow().m_value)
                          .arg(Nodeitem->getNow().m_time) + "</font></b>");
}

//新节点到来
void ZBNNMW::AddNodeToMap(const Node&m_node){
    //如果是协调器节点
    if (m_node.getDescription() == Coordinator)  {
        clearAllNode();
    }

    ZigBeeNode *parent = FindParent(m_node);//父亲节点
    ZigBeeNode *N = new ZigBeeNode(m_node,get_pos(parent),scene);

    if(parent != NULL){//有父亲，则有边相连
        /**
         * @brief new_adge 两个节点之间的边缘线
         * test 父节点 n 此节点
         */
        Edge *new_adge = new Edge(parent,N);
        scene->addItem(new_adge);
    } else {

    }
    nodelist.push_front(N);
    scene->update();
}
void ZBNNMW::Bangding(QString adress1, QString adress2){

    Child_ParentMaps.insert(adress1,adress2);

}

void ZBNNMW::RemoveEdges(QList<Edge *> m_edge){
    foreach(Edge*n_Edge,m_edge){

        scene->removeItem(n_Edge);
        delete n_Edge;
    }


}

void ZBNNMW::ChangNodeState(const Node &node){
    help(node.getDescription(),node.getAddress(),node.getParentAd(),
         node.getName(),node.getState());;
}


/**
 * @brief ZBNNMW::help add by zhou xiang
 * @param type
 * @param addr
 * @param paddr
 * @param _name
 * @param status
 */
void ZBNNMW::help(int type,const QString &addr, const QString &paddr,
                  ushort _name,bool status)
{
    if (type == Coordinator) {
        clearAllNode();
        addNode(type,addr,paddr,_name,status);
        //  emit sig_tree_clear();
        return;
    }
    foreach(ZigBeeNode *m_node,nodelist){
        Node *t = m_node->ge_NodeData();
        if (t->getName() == _name) {
            m_node->changeStatus(status);
            //这个点在图中
            if (t->getParentAd() != paddr) {
                ZigBeeNode *p = FindParent(t->getParentAd());
                t->setParentAd(paddr);
                removeSameEage(m_node->edges(),p->edges());
                ZigBeeNode *n = FindParent(paddr);
                m_node->setParentNode(n);
                Edge*new_adge=new Edge(m_node,n);
                scene->addItem(new_adge);
            }
            return;
        }
    }
}




void ZBNNMW::ChangNodeState(int type,const QString &addr, const QString &paddr,
                            ushort _name,bool status)
{

    help(type,addr,paddr,_name,status);

}

void ZBNNMW::addNode(int type,const QString &addr, const QString &paddr,
                     ushort _name,bool status)
{
    Node n;
    n.setAddress(addr);
    n.setParentAd(paddr);
    n.setName(_name);
    n.setState(status);
    n.setDescription((NodeType)(type));
    AddNodeToMap(n);

}

ZigBeeNode*ZBNNMW::FindParent(const Node&n_nde){
    ZigBeeNode*parentnode=NULL;

    foreach(ZigBeeNode*m_node,nodelist){
        if(m_node->ge_NodeData()->getAddress() == n_nde.getParentAd()){
            parentnode=m_node;
            break;
        }

    }


    return parentnode;
}


/**
 * @brief ZBNNMW::FindParent 写的很烂的一个函数，
 * @param s 父节点地址
 * @return
 */
ZigBeeNode * ZBNNMW::FindParent(const QString &s)
{
    ZigBeeNode*parentnode=NULL;

    foreach(ZigBeeNode*m_node,nodelist){
        if(m_node->ge_NodeData()->getAddress() == s){
            parentnode=m_node;
            break;
        }

    }
    return parentnode;
}

void ZBNNMW::UpdateMap(){
    scene->update();
}
void ZBNNMW::createSceneAndView(){
    view = new GraphicsView;
    scene = new QGraphicsScene(this);
    scene->setSceneRect(0, 0,view->width()*1.2, view->height());
    view->setScene(scene);
    showInfoItem = new QGraphicsTextItem("info info info",0,scene);
    QPointF p = view->mapToScene(view->viewport()->rect().topRight());
    p.setX(p.x() - showInfoItem->boundingRect().width() * 2);
    showInfoItem->setPos(p);
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addWidget(view);
    setLayout(mainLayout);
    connect(this->view,SIGNAL(sig_max_show()),this,SLOT(slt_max_show()));
}
void ZBNNMW::viewShowGrid(){
    if(!backgroundGrid){
        const int Gridsize=30;
        QPen pen(QColor(0,0,255,127));
        pen.setWidth(0.1);
        backgroundGrid=new QGraphicsItemGroup;
        const int MaxX=static_cast<int>(std::ceil(scene->width())/Gridsize)*Gridsize;
        const int MaxY=static_cast<int>(std::ceil(scene->height())/Gridsize)*Gridsize;
        for(int x=0;x<=MaxX;x+=Gridsize){
            QGraphicsLineItem *item=new QGraphicsLineItem(x,0,x,MaxY);
            item->setPen(pen);
            item->setZValue(-2);
            backgroundGrid->addToGroup(item);
        }
        for(int y=0;y<=MaxY;y+=Gridsize){
            QGraphicsLineItem *item=new QGraphicsLineItem(0,y,MaxX,y);
            item->setZValue(-2);
            backgroundGrid->addToGroup(item);
        }
        scene->addItem(backgroundGrid);
    }
    backgroundGrid->setVisible(true);

}

ZBNNMW::~ZBNNMW()
{
    foreach(ZigBeeNode*m_node,nodelist) {
        delete m_node;
    }
    nodelist.clear();


}

void ZBNNMW::slt_netTopologyBuild(const QString &/*value*/)
{


}

void ZBNNMW::deleteItemsByParentAdd(const QString &padd)
{
    foreach(ZigBeeNode*m_node,nodelist){
        if(m_node->ge_NodeData()->getParentAd() == padd){
            if (m_node->ge_NodeData()->getDescription() == EndDevice) {
                /**
                 *
                 *先删除在这个父节点上的边界的指针
                  */
                m_node->deleteParentEdge();
                //删除这个节点保存的执政
                RemoveEdges(m_node->edges());
                //
                m_node->clearEdgeList();
                nodelist.removeOne(m_node);
                delete m_node;
            } else {
                if (m_node->ge_NodeData()->getDescription() == Router) {
                    deleteItemsByParentAdd(m_node->ge_NodeData()->getAddress());

                    nodelist.removeOne(m_node);
                    delete m_node;
                }
            }

        }

    }


}
void ZBNNMW::slt_updataNodeValue(ushort name, int value)
{
    foreach(ZigBeeNode*m_node,nodelist) {
        if (m_node->ge_NodeData()->getName() == name) {
            m_node->setTime(QTime::currentTime().toString("hh:mm:ss"));
            m_node->setValue(value);
            return;
        }
    }

}

void ZBNNMW::clearAllNode()
{

    foreach(ZigBeeNode* m_node,nodelist) {
        m_node->deleteParentEdge();
        //删除这个节点保存的执政
        RemoveEdges(m_node->edges());
        scene->removeItem(m_node);
        delete m_node;
    }
    nodelist.clear();

}

void ZBNNMW::removeSameEage(QList<Edge *> &l1, QList<Edge *> &l2)
{
    if (l1.length() > l2.length()) {
        for (int i = 0;i < l1.length();++i) {
            if (l2.contains(l1.at(i))) {
                Edge *p = l1.at(i);
                l2.removeOne(l1.at(i));
                l1.removeAt(i);
                scene->removeItem(p);
                delete p;
            }
        }
    } else {
        for (int i = 0;i < l2.length();++i) {
            if (l1.contains(l2.at(i))) {
                Edge *p = l2.at(i);
                l1.removeOne(l2.at(i));
                l2.removeAt(i);
                scene->removeItem(p);
                delete p;
            }
        }
    }
}

void ZBNNMW::slt_max_show()
{
    GraphicsView *w = new GraphicsView();
    w->set_full_show();
    w->setAttribute(Qt::WA_DeleteOnClose);
    w->setScene(this->scene);
    w->showFullScreen();
}

/**
 * @brief ZBNNMW::get_pos
 * @param node 父节点
 * @return
 */
QPoint ZBNNMW::get_pos(ZigBeeNode *node)
{
    if (node == NULL) {
        return QPoint(scene->width() / 4 + 50 * get_index(""),
                      scene->height() / 10 + 50 * get_level(""));
    }
    return QPoint(scene->width() / 4 + 50 * get_index(node->ge_NodeData()->getAddress()),
                  scene->height() / 10 + 50 * get_level(node->ge_NodeData()->getAddress()));
}

int ZBNNMW::get_level(const QString &paddr)
{
    if (paddr.isEmpty()) {
        return 0;
    } else {
        return 1 + get_level(FindParent(paddr)->ge_NodeData()->getParentAd());
    }

}

int ZBNNMW::get_index(const QString &paddr)
{
    int re = 0;
    foreach(ZigBeeNode*m_node,nodelist){
        if(m_node->ge_NodeData()->getParentAd() == paddr){
            ++re;
        }

    }
    return re;

}


